package com.icebergteam.resumemaster;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.AssetManager;
import android.util.Base64;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.webkit.MimeTypeMap;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ProgressBar;
import android.widget.Toast;
import android.graphics.Bitmap;

import com.mnm.asynctaskmanager.core.AsyncTaskManager;
import com.mnm.asynctaskmanager.core.Task;
import com.mnm.asynctaskmanager.core.TaskProgress;

public class WebKitActivity extends Activity {
	public static String DEFAULHTURL = "file:///android_asset/templates/";
	public static String DEFAULTHRELATIVEPATH = Uri.parse("templates/")
			.getEncodedPath();
	public static String ASSETURL = "file:///android_asset/";
	final int CONMENU_SAVE_HTML = 0;
	final int CONMENU_SAVE_PDF = 1;
	final WebKitActivity WEBKITACTIVITY = this;
	private WebView m_webView;
	private ProgressBar m_progressBar;
	private String m_url;
	private JIFace iface = new JIFace();
	private String m_relativePath;
	private String m_saveFile;
	private String m_currentHtml;
	private static String className = "WEBKITACTIVITY";
	private AsyncTaskManager m_asyncTaskManager;
	private boolean javascriptInterfaceBroken;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		setContentView(R.layout.activity_webkit);
		init(savedInstanceState);
	}

	protected void onDestroy() {
		super.onDestroy();
		// /warning!!! code must be there for fixed exception leaking window
		// when rotation screen (asynctaskmanager)
		this.m_asyncTaskManager.dismissDialog();
	}

	public void init(Bundle savedInstanceState) {
		// Create manager and set this activity as context and listener
		m_asyncTaskManager = new AsyncTaskManager(this/* ,this */);
		// Handle task that can be retained before
		m_asyncTaskManager
				.handleRetainedTask(getLastNonConfigurationInstance());

		m_progressBar = (ProgressBar) findViewById(R.id.progressBar1);

		m_webView = (WebView) findViewById(R.id.webView1);
		m_webView.getSettings().setJavaScriptEnabled(true);
		if ("2.3".equals(Build.VERSION.RELEASE)) {
			javascriptInterfaceBroken = true;
		} else {
			m_webView.addJavascriptInterface(iface, "droid");
		}
		m_webView.getSettings().setBuiltInZoomControls(true);
		m_webView.getSettings().setLoadWithOverviewMode(true);
		m_webView.getSettings().setUseWideViewPort(true);
		m_webView.setWebViewClient(new WebViewClient() {
			public boolean shouldOverrideUrlLoading(WebView view, String url) {
				// This line right here is what you're missing.
				// Use the url provided in the method. It will match the member
				// URL!
				// view.loadUrl(url);
				return true;
			}

			@Override
			public void onPageStarted(WebView view, String url, Bitmap favicon) {
				m_progressBar.setVisibility(View.VISIBLE);
				super.onPageStarted(view, url, favicon);
			}

			@Override
			public void onPageFinished(WebView view, String url) {
				super.onPageFinished(view, url);
				m_progressBar.setVisibility(View.GONE);
			}
		});
		m_webView.setWebChromeClient(new WebChromeClient() {
			@Override
			public void onProgressChanged(WebView view, int newProgress) {
				m_progressBar.setProgress(newProgress);
			}

		});

		m_url = getIntent().getExtras().getString("url");

		m_relativePath = DEFAULTHRELATIVEPATH
				+ m_url.substring(m_url.length() - m_url.compareTo(DEFAULHTURL));

		m_webView.loadUrl(m_url);

		registerForContextMenu(this.m_webView);

		Intent intent = new Intent();
		intent.putExtra("load", "ok");
		setResult(RESULT_OK, intent);
	}

	@Override
	public Object onRetainNonConfigurationInstance() {
		// Delegate task retain to manager
		return m_asyncTaskManager.retainTask();
	}

	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		switch (v.getId()) {
		case R.id.webView1:
			menu.add(0, CONMENU_SAVE_HTML, 0, "Save html to sd root");
			menu.add(0, CONMENU_SAVE_PDF, 0, "Save pdf to sd root");
			break;
		}
	}

	public void registerForContextMenu(View view) {
		view.setOnCreateContextMenuListener(this);
	}

	@Override
	public boolean onContextItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case CONMENU_SAVE_HTML:
			postSaveResume(Environment.getExternalStorageDirectory()
					+ File.separator + "test.html");
			break;
		case CONMENU_SAVE_PDF:
			postSaveResume(Environment.getExternalStorageDirectory()
					+ File.separator + "test.pdf");
			break;
		}
		return super.onContextItemSelected(item);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.activity_webkit, menu);
		return true;
	}

	public static String convertFileToBase64(String fileName,
			AssetManager assetManager) {
		InputStream imageInFile = null;
		if (fileName.contains(ASSETURL)) {
			if (assetManager == null) {
				Log.e(String.format("%s - ConvertFileToBase64", className),
						"AssetManager null object");
				return null;
			}
			String pathForAssetOpen = fileName.substring(fileName.length()
					- fileName.compareTo(ASSETURL));

			Log.v(String.format("%s - ConvertFileToBase64", className), String
					.format("Path (asset directory) -- '%s'", pathForAssetOpen));
			try {
				imageInFile = assetManager.open(pathForAssetOpen);
			} catch (Exception e) {
				Log.e(String.format("%s - ConvertFileToBase64", className),
						e.getMessage());
			}
		} else {
			String path = fileName.substring(fileName.indexOf("/"));

			try {
				imageInFile = new FileInputStream(path);
			} catch (FileNotFoundException e) {
				Log.e(String.format("%s - ConvertFileToBase64", className),
						e.getMessage());
			}
			Log.v(String.format("%s - ConvertFileToBase64", className),
					String.format("Path -- '%s'", path));
		}
		String imageDataString = null;
		try {
			byte imageData[] = new byte[(int) imageInFile.available()];
			imageInFile.read(imageData);
			imageDataString = Base64.encodeToString(imageData, Base64.DEFAULT);

		} catch (Exception e) {
			Log.e(String.format("%s - ConvertFileToBase64", className),
					e.getMessage());
		}
		return imageDataString;
	}

	/* class for js injections */
	class JIFace {
		public String convertImageToBase64(String fileName) {
			// handler.post(new Runnable() { public void run() {} });
			return String.format(
					"data:image/%s;base64,%s",
					MimeTypeMap.getFileExtensionFromUrl(fileName.toString()),
					WEBKITACTIVITY.convertFileToBase64(fileName,
							WEBKITACTIVITY.getAssets()));
		}

		public void saveResume(String data) {
			m_currentHtml = "<html>" + data + "</html>";
			if (MimeTypeMap.getFileExtensionFromUrl(m_saveFile.toString())
					.equals("html")) {
				Log.v(String.format("%s - SaveResume", className),
						String.format("%s", m_saveFile));
				WEBKITACTIVITY.saveResume(m_currentHtml, m_saveFile);
			} else if (MimeTypeMap.getFileExtensionFromUrl(
					m_saveFile.toString()).equals("pdf")) {
				Log.v(String.format("%s - SaveResume", className),
						String.format("%s", m_saveFile));
				WEBKITACTIVITY.saveResumeAsPdf(m_currentHtml, m_saveFile);
			}
		}
	}

	class HtmlToPdfByCloudServiceTask extends Task {
		public HtmlToPdfByCloudServiceTask(TaskProgress message) {
			super(message);
			// TODO Auto-generated constructor stub
		}

		private final int CODE_ERROR = 0;
		private final int CODE_OK = 1;

		/*
		 * @Override protected Integer doInBackground(String... params) { try {
		 * for (int i = 10; i > 0; --i) { // Check if task is cancelled if
		 * (isCancelled()) { // This return causes onPostExecute call on UI
		 * thread return CODE_OK; }
		 * 
		 * // This call causes onProgressUpdate call on UI thread
		 * publishProgress(new TaskProgress(String.format( "Loading str%s ----",
		 * i), i)); Thread.sleep(1000); }
		 * 
		 * } catch (final Exception e) { Log.w("HtmlToPdfByCloudServiceTask",
		 * e.getMessage());
		 * 
		 * return CODE_ERROR; } return CODE_OK; }
		 */

		@Override
		protected Integer doInBackground(String... params) {
			final HttpParams param = new BasicHttpParams();
			HttpConnectionParams.setConnectionTimeout(param, 10000);
			HttpConnectionParams.setSoTimeout(param, 30000);
			try {
				publishProgress(new TaskProgress(
						"Getting responce from Cloud Service...", 0));

				DefaultHttpClient httpclient = new DefaultHttpClient(param);

				HttpPost httppost = new HttpPost(
						"http://www.pdf.gen.in/pdfgen.php");
				List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(
						1);
				nameValuePairs.add(new BasicNameValuePair("url", params[0]));
				httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

				HttpResponse response = httpclient.execute(httppost);

				publishProgress(new TaskProgress(String.format(
						"Saving responce to file '%s'...", params[1]), 50));

				InputStream inputStream = null;
				inputStream = response.getEntity().getContent();

				ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
				int bufferSize = 1024;
				byte[] buffer = new byte[bufferSize];
				int len = 0;
				while ((len = inputStream.read(buffer)) != -1) {
					byteBuffer.write(buffer, 0, len);
				}
				FileOutputStream stream = new FileOutputStream(params[1]);
				stream.write(byteBuffer.toByteArray());

				inputStream.close();
				stream.flush();
				stream.close();

			} catch (ConnectTimeoutException e) {
				final String error = String
						.format("Connection Timeout -- %s",
								param.getParameter(CoreConnectionPNames.CONNECTION_TIMEOUT));
				final String string = "Saving as pdf...";
				Log.e(String.format(
						"%s -> HtmlToPdfByCloudServiceTask -  doInBackground",
						className), error);
				showAlertDialog(error, string);
				return CODE_ERROR;
			} catch (final SocketTimeoutException e) {
				final String error = String.format("Request Timeout -- %s",
						param.getParameter(CoreConnectionPNames.SO_TIMEOUT));
				final String string = "Saving as pdf...";
				Log.e(String.format(
						"%s -> HtmlToPdfByCloudServiceTask -  doInBackground",
						className), error);
				showAlertDialog(error, string);
				return CODE_ERROR;

			} catch (final Exception e) {
				final String error = e.getMessage();
				final String string = "Saving as pdf...";
				Log.e(String.format(
						"%s -> HtmlToPdfByCloudServiceTask -  doInBackground",
						className), error);
				showAlertDialog(error, string);
				return CODE_ERROR;
			}
			return CODE_OK;
		}

		@Override
		protected void onCancelled() {
			// TODO Auto-generated method stub
			Toast.makeText(WEBKITACTIVITY, "File saving as pdf canceled",
					Toast.LENGTH_SHORT).show();
			super.onCancelled();
		}

		@Override
		protected void onPostExecute(Integer result) {
			switch (result) {
			case CODE_ERROR:
				Log.e(String.format(
						"%s -> HtmlToPdfByCloudServiceTask -  onPostExecute",
						className), "Error task write pdf");
				Toast.makeText(WEBKITACTIVITY, "Error task write pdf",
						Toast.LENGTH_SHORT).show();
				break;
			case CODE_OK:
				Log.v(String.format(
						"%s -> HtmlToPdfByCloudServiceTask -  onPostExecute",
						className), "File saved as pdf");
				Toast.makeText(WEBKITACTIVITY, "File saved as pdf",
						Toast.LENGTH_SHORT).show();
				break;
			}
			super.onPostExecute(result);
		}
	}

	public void postSaveResume(final String fileName) {
		m_saveFile = fileName;
		// saveResumeAsPdf("<p>dsaasdsad</p>", fileName);
		String ht = "javascript:window.droid.saveResume(document.getElementsByTagName('html')[0].innerHTML);";

		m_webView.loadUrl(ht);
	}

	/*
	 * get html for save to file and copy resources - fileName -- variable
	 * parent class m_saveFile
	 */
	public void saveResume(final String data, final String fileName) {
		WEBKITACTIVITY.runOnUiThread(new Runnable() {
			public void run() {
				try {
					File root = new File(fileName);
					if (!root.getParentFile().exists()) {
						root.getParentFile().mkdirs();
						Log.v(String.format("%s - SaveFile", className), String
								.format("'%s' -- parent directory created",
										root.getParentFile().getAbsolutePath()));
					}

					File file = new File(root.getAbsolutePath());
					FileOutputStream fos = new FileOutputStream(file);
					fos.write(data.getBytes());
					fos.close();

					Log.v(String.format("%s - SaveFile", className),
							String.format("'%s' -- edited file saved",
									root.getAbsolutePath()));

					/*
					 * if (m_url.contains(ASSETURL)) { String pathForAssetOpen =
					 * DEFAULTHRELATIVEPATH + m_url.substring( m_url.length() -
					 * m_url.compareTo(DEFAULHTURL), m_url.lastIndexOf("/"));
					 * 
					 * Log.v("SaveFile", String.format(
					 * "Path 'from' asset directory (copy resources)-- '%s'",
					 * pathForAssetOpen)); copyDirectory(pathForAssetOpen, file
					 * .getParentFile().getAbsolutePath(), true,
					 * Arrays.asList(new File(m_url).getName() .split("\\?")[0],
					 * "index.html", "xml", "js")); } else { String path =
					 * m_url.substring(m_url.indexOf("/"),
					 * m_url.lastIndexOf("/")); Log.v("SaveFile", String.format(
					 * "Path 'from' (copy resources) -- '%s'", path));
					 * copyDirectory(path, file.getParentFile()
					 * .getAbsolutePath(), false, Arrays.asList( new
					 * File(m_url).getName().split("\\?")[0], "index.html",
					 * "xml", "js"));
					 * 
					 * 
					 * }
					 */
					Toast.makeText(WEBKITACTIVITY, "File saved as html",
							Toast.LENGTH_SHORT).show();
				} catch (Exception e) {
					Log.e(String.format("%s - SaveFile", className),
							e.getMessage());
				}
			}
		});
	}

	public void saveResumeAsPdf(final String data, final String fileName) {
		WEBKITACTIVITY.runOnUiThread(new Runnable() {
			public void run() {
				if (!m_asyncTaskManager.isWorking())
					m_asyncTaskManager
							.setupTask((Task) new HtmlToPdfByCloudServiceTask(
									new TaskProgress("Saving as pdf..."))
									.execute(data, fileName));
			}
		});
	}

	/**
	 * @param error
	 * @param string
	 */
	private void showAlertDialog(final String error, final String string) {
		WEBKITACTIVITY.runOnUiThread(new Runnable() {
			public void run() {
				AlertDialog.Builder builder = new AlertDialog.Builder(
						WEBKITACTIVITY);

				builder.setTitle(string)
						.setMessage(error)
						.setCancelable(false)
						.setPositiveButton("Ok",
								new DialogInterface.OnClickListener() {
									public void onClick(DialogInterface dialog,
											int id) {
										// do something if OK
									}
								});
				builder.create().show();
			}
		});
	}

	/*
	 * private void copyDirectory(String inputTemplateName, String
	 * outputTemplateName, Boolean IsAssetsDirectory, List<String> ignoreList) {
	 * if (IsAssetsDirectory) { FilesUtils.copyDirectory(inputTemplateName,
	 * outputTemplateName, getAssets(), ignoreList); } else {
	 * FilesUtils.copyDirectory(new File(inputTemplateName), new File(
	 * outputTemplateName), ignoreList); } }
	 */
}